using System.Runtime.CompilerServices;
#if MYCODE
using BepuUtilities.Vectors;
#else
using System.Numerics;
#endif
namespace BepuUtilities
{

    public struct Matrix2x2Wide
    {
        /// <summary>
        /// 矩阵的第一行。
        /// </summary>
        public Vector2Wide X;
        /// <summary>
        /// 矩阵的第二行。
        /// </summary>
        public Vector2Wide Y;


        /// <summary>
        /// 将一个矩阵乘以另一个矩阵,其中第二个矩阵被采样,就像它被转置一样：result=a*transspose(B)。
        /// </summary>
        /// <param name="a">对中的第一个矩阵。</param>
        /// <param name="b">要采样的矩阵,就像它与第一个矩阵相乘时被转置一样。</param>
        /// <param name="result">乘法a*转置(B)的结果。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void MultiplyByTransposeWithoutOverlap(in Matrix2x2Wide a, in Matrix2x2Wide b, out Matrix2x2Wide result)
        {
            result.X.X = a.X.X * b.X.X + a.X.Y * b.X.Y;
            result.X.Y = a.X.X * b.Y.X + a.X.Y * b.Y.Y;
            result.Y.X = a.Y.X * b.X.X + a.Y.Y * b.X.Y;
            result.Y.Y = a.Y.X * b.Y.X + a.Y.Y * b.Y.Y;
        }


        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void TransformWithoutOverlap(in Vector2Wide v, in Matrix2x2Wide m, out Vector2Wide result)
        {
            result.X = v.X * m.X.X + v.Y * m.Y.X;
            result.Y = v.X * m.X.Y + v.Y * m.Y.Y;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Transform(in Vector2Wide v, in Matrix2x2Wide m, out Vector2Wide result)
        {
            TransformWithoutOverlap(v, m, out var temp);
            result = temp;
        }


        /// <summary>
        /// 将矩阵中的每个分量乘以给定的标量值。
        /// </summary>
        /// <param name="m">要缩放的矩阵。</param>
        /// <param name="scale">要应用于矩阵组件的缩放值。</param>
        /// <param name="result">包含缩放组件的结果矩阵。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Scale(in Matrix2x2Wide m, in Vector<float> scale, out Matrix2x2Wide result)
        {
            result.X.X = m.X.X * scale;
            result.X.Y = m.X.Y * scale;
            result.Y.X = m.Y.X * scale;
            result.Y.Y = m.Y.Y * scale;
        }

        /// <summary>
        /// 将一个矩阵的组件添加到另一个矩阵。
        /// </summary>
        /// <param name="a">要添加的第一个矩阵。</param>
        /// <param name="b">要添加的第二个矩阵。</param>
        /// <param name="result">两个给定矩阵的总和。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Add(in Matrix2x2Wide a, in Matrix2x2Wide b, out Matrix2x2Wide result)
        {
            Vector2Wide.Add(a.X, b.X, out result.X);
            Vector2Wide.Add(a.Y, b.Y, out result.Y);
        }

        /// <summary>
        /// 从一个矩阵中减去另一个矩阵的分量。
        /// </summary>
        /// <param name="a">要从..中减去的矩阵</param>
        /// <param name="b">要从另一个矩阵中减去的矩阵。</param>
        /// <param name="result">减法的结果。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Subtract(in Matrix2x2Wide a, in Matrix2x2Wide b, out Matrix2x2Wide result)
        {
            Vector2Wide.Subtract(a.X, b.X, out result.X);
            Vector2Wide.Subtract(a.Y, b.Y, out result.Y);
        }



        /// <summary>
        /// 反转给定矩阵。
        /// </summary>
        /// <param name="Matrix">要反转的矩阵。</param>
        /// <param name="result">倒置矩阵。</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void InvertWithoutOverlap(in Matrix2x2Wide m, out Matrix2x2Wide inverse)
        {
            var determinantInverse = Vector<float>.One / (m.X.X * m.Y.Y - m.X.Y * m.Y.X);
            inverse.X.X = m.Y.Y * determinantInverse;
            inverse.X.Y = -m.X.Y * determinantInverse;

            inverse.Y.X = -m.Y.X * determinantInverse;
            inverse.Y.Y = m.X.X * determinantInverse;

        }
    }
}
